package com.taysear.parcel;

import java.util.Arrays;
import java.util.Date;

import javax.persistence.EntityManager;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;

import com.taysear.parcel.domain.Loadingsheet;
import com.taysear.parcel.domain.Parcel;
import com.taysear.parcel.domain.User;
import com.taysear.parcel.fieldfactory.UserFieldFactory;
import com.taysear.parcel.util.Constants;
import com.vaadin.addon.jpacontainer.JPAContainer;
import com.vaadin.addon.jpacontainer.JPAContainerFactory;
import com.vaadin.addon.jpacontainer.fieldfactory.FieldFactory;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.data.util.filter.And;
import com.vaadin.data.util.filter.Compare.Equal;
import com.vaadin.data.util.filter.Between;
import com.vaadin.data.util.filter.Not;
import com.vaadin.data.util.filter.Or;
import com.vaadin.terminal.Sizeable;
import com.vaadin.ui.AbsoluteLayout;
import com.vaadin.ui.Button;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.Label;
import com.vaadin.ui.MenuBar;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalSplitPanel;
import com.vaadin.ui.MenuBar.Command;
import com.vaadin.ui.MenuBar.MenuItem;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.themes.Runo;

public class MainWindow extends VerticalLayout{

	ParcelApplication app;
	HorizontalLayout topBarLayout;
	MenuBar menu;
	Label userFullName;
	Button logout;
	HorizontalLayout mainLayout;

	JPAContainer<Loadingsheet> loadingsheets = null;
	LoadingsheetTable loadingsheetTable = null;
	MainWindow mainWindow;

	public MainWindow(ParcelApplication app) {
		this.app = app;
		this.mainWindow = this;
		
		topBarLayout = new HorizontalLayout();
		topBarLayout.addStyleName("topBarLayout");
		
		menu = new MenuBar();
		userFullName = new Label();
		
		logout = new Button("Logout");
		mainLayout = new HorizontalLayout();
		mainLayout.addStyleName("mainLayout");
		
		Subject currentUser = SecurityUtils.getSubject();

		if (currentUser.isPermitted(PermissionsConstants.PERMISSION_MENU_PARCEL)) {
			final MenuBar.MenuItem parcel = menu.addItem("Parcel", null);
			if (currentUser.isPermitted(PermissionsConstants.PERMISSION_MENU_PARCEL_CREATE))
				parcel.addItem("Create", createParcelCommando);
			if (currentUser.isPermitted(PermissionsConstants.PERMISSION_MENU_PARCEL_OUTGOING))
				parcel.addItem("Outgoing", outgoingParcelsCommando);
			if (currentUser.isPermitted(PermissionsConstants.PERMISSION_MENU_PARCEL_INCOMMING))
				parcel.addItem("Incomming", incommingParcelsCommando);
		}
		
		if (currentUser.isPermitted(PermissionsConstants.PERMISSION_MENU_LOADINGSHEET)) {
			final MenuBar.MenuItem loadingsheetMenu = menu.addItem("Loading sheet", null);
			if (currentUser.isPermitted(PermissionsConstants.PERMISSION_MENU_LOADINGSHEET_OUTGOING))
				loadingsheetMenu.addItem("Outgoing", outgoingLoadingsheetCommando);
			if (currentUser.isPermitted(PermissionsConstants.PERMISSION_MENU_LOADINGSHEET_INCOMMING))
				loadingsheetMenu.addItem("Incomming", incommingLoadingsheetCommando);
		}
		
		if (currentUser.isPermitted(PermissionsConstants.PERMISSION_MENU_REPORTS)) {
			final MenuBar.MenuItem reports = menu.addItem("Reports", null);
			if (currentUser.isPermitted(PermissionsConstants.PERMISSION_MENU_REPORTS_SALES))
				reports.addItem("Daily sales", dailySalesCommando);
			if (currentUser.isPermitted(PermissionsConstants.PERMISSION_MENU_REPORTS_CANCELLED_SALES))
				reports.addItem("Daily cancelled sales", dailyCancelledSalesCommando);
		}

		if (currentUser.isPermitted(PermissionsConstants.PERMISSION_MENU_SETUP)) {
			final MenuBar.MenuItem setup = menu.addItem("Setup", null);
			if (currentUser.isPermitted(PermissionsConstants.PERMISSION_MENU_SETUP_SYSTEM_SETTINGS))
				setup.addItem("System settings", setupCommando);
			if (currentUser.isPermitted(PermissionsConstants.PERMISSION_MENU_SETUP_USER_MANAGEMENT))
				setup.addItem("User management", userManagementCommando);
		}
		final MenuBar.MenuItem setup = menu.addItem("Preferrence", null);
		setup.addItem("Password reset", passwordResetCommando);
		
		menu.addStyleName("menu");
		
		userFullName.setValue("Welcome, " + app.getUser());
		userFullName.addStyleName("userFullName");
		
		logout.addStyleName("logout "+Runo.BUTTON_SMALL);
		logout.addListener(new ParcelApplication.LogoutListener(this.app));
		
		topBarLayout.addComponent(menu);
		topBarLayout.addComponent(userFullName);
		topBarLayout.addComponent(logout);
		topBarLayout.setSizeFull();
		addComponent(topBarLayout);
		
		mainLayout.setSpacing(true);
		addComponent(mainLayout);
	}
	
	private Command createParcelCommando = new Command() {
		public void menuSelected(MenuItem selectedItem) {
			mainLayout.removeAllComponents();
			ParcelForm pf = new ParcelForm(app, null, "Create parcel", 1);
			pf.initForm();
			pf.fieldFactory.receiverIdentification.setVisible(false);
	    	pf.fieldFactory.receiverIdentificationLabel.setVisible(false);
			pf.addStyleName("createParcelForm");			
            mainLayout.addComponent(pf);
        }
    };
    
    private Command outgoingParcelsCommando = new Command() {
		public void menuSelected(MenuItem selectedItem) {
			mainLayout.removeAllComponents();
			ParcelWindow parcelWindow = new ParcelWindow(app, mainWindow, 1, false);
			mainLayout.addComponent(parcelWindow);
        }
    };
    
    private Command incommingParcelsCommando = new Command() {
		public void menuSelected(MenuItem selectedItem) {
			mainLayout.removeAllComponents();
			ParcelWindow parcelWindow = new ParcelWindow(app, mainWindow, 2, false);
			mainLayout.addComponent(parcelWindow);
		}
    };
    
    private Command setupCommando = new Command() {
		public void menuSelected(MenuItem selectedItem) {
			mainLayout.removeAllComponents();
			AutoCrudViews ac = new AutoCrudViews(app);
			ac.addStyleName("crudLayout");
			ac.setWidth("870px");
			ac.setHeight("520px");
			mainLayout.addComponent(ac);
        }
    };
    
    private Command userManagementCommando = new Command() {
		public void menuSelected(MenuItem selectedItem) {
			mainLayout.removeAllComponents();
			BasicCrudView<User> view = new BasicCrudView<User>(app, User.class, app.PERSISTENCE_UNIT, new UserFieldFactory(app));
			view.setVisibleTableProperties("username", "employee");
			view.setVisibleAddFormProperties("username", "password", "employee");
			view.setVisibleEditFormProperties("userId", "username", "password");
			view.addStyleName("crudLayout");
			view.setCaption("");
			view.setWidth("870px");
			view.setHeight("520px");
			view.showPermissionButtion();
			mainLayout.addComponent(view);
        }
    };
    
    private Command outgoingLoadingsheetCommando = new Command() {
		public void menuSelected(MenuItem selectedItem) {
			mainLayout.removeAllComponents();
			LoadingsheetWindow loadingsheetWindow = new LoadingsheetWindow(app, mainWindow, true);
			mainLayout.addComponent(loadingsheetWindow);
        }
    };
    
    private Command incommingLoadingsheetCommando = new Command() {
		public void menuSelected(MenuItem selectedItem) {
			mainLayout.removeAllComponents();
			LoadingsheetWindow loadingsheetWindow = new LoadingsheetWindow(app, mainWindow, false);
			mainLayout.addComponent(loadingsheetWindow);
        }
    };
    
    private Command dailySalesCommando = new Command() {
		public void menuSelected(MenuItem selectedItem) {
			mainLayout.removeAllComponents();
			ParcelWindow parcelWindow = new ParcelWindow(app, mainWindow, 3, false);
			mainLayout.addComponent(parcelWindow);
        }
    };
    
    private Command dailyCancelledSalesCommando = new Command() {
		public void menuSelected(MenuItem selectedItem) {
			mainLayout.removeAllComponents();
			ParcelWindow parcelWindow = new ParcelWindow(app, mainWindow, 3, true);
			mainLayout.addComponent(parcelWindow);
        }
    };
    
    private Command passwordResetCommando = new Command() {
		public void menuSelected(MenuItem selectedItem) {
			mainLayout.removeAllComponents();
			PasswordResetLayout passwordResetLayout = new PasswordResetLayout(app);
			mainLayout.addComponent(passwordResetLayout);
        }
    };
    
    public JPAContainer<Parcel> todaysParcels(String station){
    	JPAContainer<Parcel> parcels = JPAContainerFactory.make(Parcel.class, app.PERSISTENCE_UNIT);
		Equal sid = equalUserStationId(station);
		Date start = app.getStartOfADay(new Date());
		Date end = app.getEndOfADay(new Date());
		Between date = new Between("date", start, end);
		And and = new And(sid,date);
		parcels.addContainerFilter(and);
		return parcels;
    }
    
    public Equal equalUserStationId(String stationType){
    	return new Equal("parcelDetail."+stationType+".stationId",app.getUser().getEmployee().getStation().getStationId());
    }
    
    public Equal equalUserSubstationId(String substationType){
    	return new Equal("parcelDetail."+substationType+".substationId",app.getUser().getEmployee().getSubstation().getSubstationId());
    }
    
    public BeanItemContainer<Parcel> getNotLoadedParcels(String stationType, String substationType){
    	JPAContainer<Parcel> parcels = JPAContainerFactory.make(Parcel.class, app.PERSISTENCE_UNIT);
		Equal sid = equalUserStationId(stationType);
		Equal subid = equalUserSubstationId(substationType);
    	Equal statusNew = new Equal("parcelStatus.parcelStatusId", Constants.PARCEL_STATUS_NEW);
    	Equal statusEdited = new Equal("parcelStatus.parcelStatusId", Constants.PARCEL_STATUS_EDITED);
    	Equal statusUnloaded = new Equal("parcelStatus.parcelStatusId", Constants.PARCEL_STATUS_UNLOADED);
    	Equal statusUndelivered = new Equal("parcelStatus.parcelStatusId", Constants.PARCEL_STATUS_UNDELIVERED);
    	parcels.addContainerFilter(new And(sid, subid, new Or(statusNew, statusEdited, statusUnloaded, statusUndelivered)));
    	BeanItemContainer<Parcel> beanItemContainer = new BeanItemContainer<Parcel>(Parcel.class);
		for (Object o : parcels.getItemIds()) {
			beanItemContainer.addBean(parcels.getItem(o).getEntity());
		}
		return beanItemContainer;
    }
    
    public BeanItemContainer<Parcel> getParcelsByLoadingsheetId(String stationType, Integer loadingsheetId){
    	JPAContainer<Parcel> parcels = JPAContainerFactory.make(Parcel.class, app.PERSISTENCE_UNIT);
		Equal sid = equalUserStationId(stationType);
    	Equal loadingsheet = new Equal("loadingsheet.loadingsheetId", loadingsheetId);
    	parcels.addContainerFilter(new And(sid, loadingsheet));
    	BeanItemContainer<Parcel> beanItemContainer = new BeanItemContainer<Parcel>(Parcel.class);
		for (Object o : parcels.getItemIds()) {
			beanItemContainer.addBean(parcels.getItem(o).getEntity());
		}
		return beanItemContainer;
    }
}
